home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1997 October / macformat-055.iso / mac / Shareware Plus / Developers / VideoToolbox / VideoToolboxSources / Seconds.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-30  |  4.7 KB  |  140 lines  |  [TEXT/CWIE]

  1. /*
  2. Seconds.c
  3.  
  4.     s=Seconds();
  5. returns the number of seconds (as a double, with 20 µs or better
  6. accuracy) since the computer started up.
  7.  
  8. If possible, we use the new UpTime routine, which uses the PPC's
  9. internal clock to get an accurate time with 20 nanosecond or better
  10. precision, but it's only available on PCI PowerMacs. Otherwise we use
  11. the Microseconds routine, which has 20 microseconds precision, and is
  12. part of Mac OS 7.
  13.  
  14. UpTime offers stable timing even when interrupts are blocked (e.g. by
  15. calls to cscSetEntries). It is my unconfirmed impression that
  16. Microseconds advances at a reduced rate when we're repeatedly calling
  17. cscSetEntries on my PowerMac 7500.
  18.  
  19. Microseconds() is documented in "Inside Mac: OS Utilities".
  20.  
  21. UpTime is documented in "Designing PCI Cards and Drivers for Power
  22. Macintosh Computers".
  23.  
  24. UpTime and Microseconds are briefly described in Martin Minow (1996)
  25. Timing on the Macintosh, develop 26.
  26. <http://devworld.apple.com/dev/techsupport/develop/issue26/minow.html>
  27.  
  28. The shared library DriverServicesLib must be weak linked with this
  29. project, when compiling for ppc; it's not needed when compiling for 68k.
  30.  
  31. 4/28/97 The latest word from Apple is "The UpTime call will not be
  32. implemented on earlier PowerPCs under Tempo (Mac OS 8). That was the
  33. plan under Maxwell, but is no longer being considered."
  34.  
  35. HISTORY:
  36. 5/8/96    dgp    Wrote the MEX routine Secs.c.
  37.                 dhb    Changed name to GetSecs, cosmetic editing.
  38.                 dgp Use UpTime if available.
  39. 6/6/96    dgp    Omit DriverServicesLib calls when compiling for 68K.
  40. 1/26/97    dgp minor changes to allow successful 68K compile.
  41. 1/26/97    dgp extracted most of the code from GetSecs.c to create this new VideoToolbox
  42.                         Seconds.c, to make this good timebase more widely available.
  43. 2/9/97    dgp    corrected function name in error message.
  44. 3/19/97    dgp    minor tuning of the floating point arithmetic
  45. */
  46. #include "VideoToolbox.h"
  47.  
  48. #if GENERATINGPOWERPC
  49.     #if UNIVERSAL_HEADERS>1
  50.         #ifndef __CODEFRAGMENTS__
  51.             #include <CodeFragments.h>
  52.         #endif
  53.     #endif
  54. #endif
  55.  
  56. typedef UnsignedWide AbsoluteTime;    // Types.h
  57. typedef UnsignedWide Nanoseconds;    // DriverServices.h
  58. extern AbsoluteTime UpTime(void);    // DriverServices.h
  59. extern Nanoseconds AbsoluteToNanoseconds(AbsoluteTime absoluteTime);// DriverServices.h
  60.  
  61. double Seconds(void)
  62. {
  63.     static Boolean firstTime=1,upTimeAvailable=0;
  64.     double s;
  65.  
  66.     if(firstTime){
  67.         long version;
  68.  
  69.         // Make sure Microseconds trap is available.
  70.         Gestalt(gestaltSystemVersion,&version);
  71.         if(version<0x700)PrintfExit("%s: your System is too old; we need at least System 7.\n",__FILE__);
  72.  
  73.         // Is UpTime available?
  74.         // The UpTime glue is in the DriverServicesLib shared library, which is
  75.         // weak-linked, so we must load it before using it. If we fail, 
  76.         // we mustn't try to access the library's exports.
  77.         upTimeAvailable=IsDriverServicesLibAvailable();
  78.         firstTime=0;
  79.     }
  80.     if(upTimeAvailable && GENERATINGPOWERPC){
  81.         #if GENERATINGPOWERPC    // we don't want to deal with shared libraries in THINK C
  82.             AbsoluteTime elapsedTime;
  83.             Nanoseconds elapsedNanoseconds;   // an UnsignedWide integer
  84.  
  85.             elapsedTime=UpTime();
  86.             elapsedNanoseconds=AbsoluteToNanoseconds(elapsedTime);
  87. // NOTE: 4294967296.0 == (double)0x10000*0x10000
  88.             s=elapsedNanoseconds.lo+4294967296.0*elapsedNanoseconds.hi;
  89.             s/=1e9;
  90.         #endif
  91.     }else{
  92.         UnsignedWide microTicks;
  93.  
  94.         Microseconds(µTicks);
  95.         s=microTicks.lo+4294967296.0*microTicks.hi;
  96.         s*=1e-6;
  97.     }
  98.     return s;
  99. }
  100.  
  101. Boolean IsDriverServicesLibAvailable(void)
  102. {
  103.     long error;
  104.     Boolean isAvailable;
  105.  
  106.     if(1){
  107.         // This extra test isn't strictly necessary. 
  108.         // However, calling Gestalt is fast, whereas calling GetSharedLibrary requires
  109.         // a disk access, so we only call GetSharedLibrary if we expect it to succeed. 
  110.         Boolean pci;
  111.         long value,version;
  112.         #define gestaltNameRegistryVersion 'nreg'    // support old Gestalt.h header
  113.  
  114.         error=Gestalt(gestaltNameRegistryVersion,&value);
  115.         pci=!error;    // are there PCI slots?
  116.         Gestalt(gestaltSystemVersion,&version);
  117.         isAvailable=(pci || version>=0x800);    // according to Apple's 1995 docs.
  118.     }
  119.     #if GENERATINGPOWERPC && CFMSYSTEMCALLS
  120.         if(isAvailable){
  121.             // The DriverServicesLib shared library is
  122.             // weak-linked, so we must load it before using it. If we fail, 
  123.             // we mustn't try to access the library's exports.
  124.             CFragConnectionID connID;
  125.             Ptr mainAddr;
  126.             Str255 errorMessage;
  127.             long value;
  128.             
  129.             error=Gestalt(gestaltCFMAttr,&value);    // Code Fragment Manager?
  130.             if(!error)error=GetSharedLibrary((ConstStr63Param)"\pDriverServicesLib"
  131.                 ,kAnyCFragArch,kFindCFrag,&connID,&mainAddr,errorMessage);
  132.             isAvailable=!error;
  133.             if(error)printf("WARNING: IsDriverServicesLibAvailable: GetSharedLibrary error=%ld, %s\n",(long)error,p2cstr(errorMessage));
  134.         }
  135.     #else
  136.         isAvailable=0;
  137.     #endif
  138.     return isAvailable;
  139. }
  140.